package rabbitmq

import (
	"fmt"
	"github.com/streadway/amqp"
)

var RabbitIns *Ribbt
// 发布订阅模式
type Ribbt struct {
	conn *amqp.Connection  // 连接信息
	ch *amqp.Channel     // 通道

	TyMode string // 模式
	ExName string // 交换机名称
	Qname string // 队列名称
	RouteKey string // 路由地址
	Url string // 连接地址
}

func GetRabbitInstanse(r *Ribbt) {
	if RabbitIns != nil {
		RabbitIns = RabbitIns
	}else {
		_ = r.GetRabbit()
		RabbitIns = r
	}
}

func(r *Ribbt) GetRabbit() error {
	conn, err := amqp.Dial(r.Url)
	if err != nil {
		return err
	}
	r.conn = conn
	ch, err := conn.Channel()
	ch.Confirm(false) // 开启confirm模式
	if err != nil {
		return err
	}
	r.ch = ch
	return  nil
}

func(r *Ribbt) CreateExTopic(exName string) error {
	if exName != "" {
		r.ExName = exName
	}
	return r.ch.ExchangeDeclare(r.ExName, r.TyMode, true, false,false, false, nil)
}

// 发送消息
func (r *Ribbt) PublishMsg(msg string) error {
	// 判断r.channel是否存在，不存在则重新穿件通道
	confirm := make(chan amqp.Confirmation, 100)
	err := r.ch.Publish(r.ExName, r.RouteKey, false, false, amqp.Publishing{
		DeliveryMode: amqp.Persistent,
		ContentType: "text/plain",
		Body:        []byte(msg),
	})
	rconfirm := r.ch.NotifyPublish(confirm)
	for  v := range rconfirm {
		fmt.Println("ack: ",v.DeliveryTag, v.Ack)
		if v.Ack == true {
			r.ch.Ack(v.DeliveryTag, false)
		}else if v.Ack == false {
			r.ch.Nack(v.DeliveryTag, false, false)
		}
	}

	return err
}

// 接受消息
func (r *Ribbt) Customer(qName string) (<-chan amqp.Delivery,error) {
	if qName != "" {
		r.Qname = qName
	}
	q, err := r.ch.QueueDeclare(r.Qname, true, false, false, false, nil)
	if err != nil {
		return nil, err
	}
	err = r.ch.QueueBind(q.Name, r.RouteKey, r.ExName, false, nil)
	if err != nil {
		return nil, err
	}
	r.ch.Qos(1,0, false)
	msgs, err := r.ch.Consume(q.Name, "", false, false, false, false, nil)

	return msgs, nil
}

func (r * Ribbt)CloseRabbit() {
	defer r.ch.Close()
	defer r.ch.Close()
}